// @Author EthanScriptOn
// @Desc
package tool

import (
	"fmt"
	"gitee.com/fatzeng/srf_switch_basic_components/custom_exp"
	"gitee.com/fatzeng/srf_switch_basic_components/util"
	"strings"
)

// errorConvert Exception formatting
func errorConvert(err error, errorTag string, errorMsg string, isTransfer bool) error {
	if err == nil {
		return nil
	}
	buildSrfSwitchFun := func(errorMsg string) *custom_exp.SrfSwitchError {
		builder := strings.Builder{}
		builder.WriteString(errorTag)
		builder.WriteString(": ")
		builder.WriteString(errorMsg)
		return custom_exp.GenerateSrfSwitchError(builder.String(), util.GetPosition(4))
	}
	if ext, ok := (err).(*custom_exp.SrfSwitchError); ok {
		if !isTransfer {
			return ext
		} else {
			return custom_exp.GenerateMultiError(buildSrfSwitchFun(errorMsg), ext)
		}
	}
	if mul, ok := (err).(*custom_exp.MultiError); ok {
		if isTransfer {
			mul.AddError(buildSrfSwitchFun(errorMsg))
		}
		return mul
	}
	return buildSrfSwitchFun(err.Error())
}

// HandleErrWithTemplate Exception handling with template information
func HandleErrWithTemplate(err *error, errorMsg string) {
	if err == nil {
		//Not handling recover in advance because empty err is a serious issue
		return
	}
	multiError := custom_exp.GenerateMultiError()
	if rec := recover(); rec != nil {
		if recoverErr, ok := rec.(error); ok {
			multiError.AddError(errorConvert(recoverErr, "[RECOVER]", errorMsg, true))
		} else {
			recoverErr = fmt.Errorf("unclear exception types: [%v]", rec)
			multiError.AddError(errorConvert(recoverErr, "[RECOVER]", errorMsg, true))
		}
	}
	multiError.AddError(errorConvert(*err, "[ERROR]", errorMsg, true))
	if len(multiError.GetErrors()) != 0 {
		*err = multiError
	}
}

// HandleErr Exception handling
func HandleErr(err *error) {
	if err == nil {
		//Not handling recover in advance because empty err is a serious issue
		return
	}
	errorMsg := "You Has Error: "
	multiError := custom_exp.GenerateMultiError()
	if rec := recover(); rec != nil {
		if recoverErr, ok := rec.(error); ok {
			multiError.AddError(errorConvert(recoverErr, "[RECOVER]", errorMsg, true))
		} else {
			recoverErr = fmt.Errorf("unclear exception types: [%v]", rec)
			multiError.AddError(errorConvert(recoverErr, "[RECOVER]", errorMsg, true))
		}
	}
	multiError.AddError(errorConvert(*err, "[ERROR]", errorMsg, true))
	if len(multiError.GetErrors()) != 0 {
		*err = multiError
	}
}

// RecordErr Exception logging
func RecordErr() string {
	var err error
	errorMsg := "You Has Error: "
	if rec := recover(); rec != nil {
		if recoverErr, ok := rec.(error); ok {
			err = errorConvert(recoverErr, "[RECOVER]", errorMsg, true)
		} else {
			recoverErr = fmt.Errorf("unclear exception types: [%v]", rec)
			err = errorConvert(recoverErr, "[RECOVER]", errorMsg, true)
		}
	}
	return err.Error()
}
